#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <fstream>

class JSerialize
{
public:
	virtual int Serialize(std::iostream& strea,int& allSize) = 0;
	virtual void ReSerialize(std::iostream& strea) = 0;
	JSerialize(void);
	~JSerialize(void);
	static std::iostream& InitStream(std::string fileName);

	static int PutChars(std::iostream& strea,const char* c,int n,int& allSize);
	//return its' self size.
	static int PutInt(std::iostream& strea,int i,int& allSize);
	//return its' self size.
	static int Serialize(std::iostream& strea,int i,int& allSize);
	//return its' self size.
	static int Serialize(std::iostream& strea,std::string s,int& allSize);
	//return its' self size.
	static int Serialize(std::iostream& strea,std::vector<int> vec,int& allSize);
	//
	static int Serialize(std::iostream& _strea,std::list<std::string> strList,int& allSize);
	//
	template <class T>
	static int Serialize(std::iostream& _strea,std::list<T> listT,int& allSize)
	{
		int classSize = 0;
		int selfSize = 0;
		PutInt(_strea,listT.size(),selfSize);
		typename std::list<T>::iterator ite = listT.begin();
		for(;ite != listT.end(); ++ite)
		{
			ite->Serialize(_strea,classSize);
		}
		selfSize += classSize;
		allSize += selfSize;
		return selfSize;
	}

	static int Serialize( std::iostream& _strea,std::fstream& _fs,int& _allSize );
	//change "_offSize" data as "_data", then move pointer to cur
	static void Verify(std::iostream& _strea,int _data,int _offSize);
	//return the int that get
	static int GetInt(std::iostream& _strea,int intSize);

	//
	static std::string ReSerializeString(std::iostream& _strea);

	static int ReSerializeInt(std::iostream& strea);

	static std::vector<int> ReSerializeIntArray(std::iostream& strea);

	static std::list<std::string> ReSerializeStringList(std::iostream& strea);

	template <class T>
	static std::list<T> ReSerializeList(std::iostream& _strea)
	{
		std::list<T> listT;
		int listSize = GetInt(_strea,sizeof(int));
		for(int i = 0;i < listSize; ++i)
		{
			T t;
			t.ReSerialize(_strea);
			listT.push_back(t);
		}
		return listT;
	}

	static void ReSerializeFstream(std::iostream& _strea,std::fstream& _fs);
};

